# yun-cha-coffee PyCharm
# 2025/8/30 16:58
# YunCha-Coffee PyCharm
# user 86155
# 2025/8/30 1:15
import datetime
import time
import random
from dataclasses import Field
from decimal import Decimal
from venv import logger

from fastapi import APIRouter, HTTPException, Depends, Query
from typing import Union, List, Optional, Literal
from app.dependencies import require_admin, get_current_active_user  # 假设存在管理员验证依赖
from tortoise.exceptions import DoesNotExist, OperationalError

from app.dependencies import get_current_user
from app.models import *
from pydantic import BaseModel, validator

order_api = APIRouter(prefix="/order")


@order_api.get("/my_order", summary="用户查询自己的所有订单")
async def get_user_orders(
        id:int,
        current_user: User = Depends(get_current_user)  # 依赖注入获取当前用户
):
    """
    当前登录用户查询自己的订单列表
    - 仅返回当前认证用户的订单
    - 自动过滤非当前用户的订单数据
    - 包含订单基本信息和订单项详情
    """
    try:
        # 1. 记录用户操作日志
        logger.info(f"用户 {current_user.id} 开始查询自己的订单")

        # 2. 查询当前用户的订单（带预加载关联数据）
        try:
            orders = await Order.filter(user_id=current_user.id).prefetch_related(
                "address",  # 预加载地址信息
                "items"  # 预加载订单项
            ).order_by("-created_at").all()  # 按创建时间降序

            # 3. 构造响应数据
            order_list = []
            for order in orders:
                order_data = {
                    "id": order.id,
                    "order_number": order.order_number,
                    "total_amount": float(order.total_amount),
                    "status": order.status,
                    "payment_method": order.payment_method,
                    "payment_status": order.payment_status,
                    "refund_status": order.refund_status,
                    "payment_at": order.payment_at.isoformat() if order.payment_at else None,
                    "remark": order.remark,
                    "created_at": order.created_at.isoformat(),
                    "updated_at": order.updated_at.isoformat(),
                    "items": []
                }

                # 添加订单项
                for item in order.items:
                    order_data["items"].append({
                        "id": item.id,
                        "product_id": item.product_id,
                        "product_type": item.product_type,
                        "product_name": item.product_name,
                        "product_image": item.product_image,
                        "price": float(item.price),
                        "quantity": item.quantity,
                        "total_price": float(item.total_price)
                    })

                order_list.append(order_data)

            return {
                "code": 200,
                "message": "查询成功",
                "data": order_list
            }

        except OperationalError as db_err:
            logger.error(f"用户 {current_user.id} 查询订单时数据库异常: {str(db_err)}")
            raise HTTPException(
                status_code=503,
                detail="服务暂时不可用，请稍后重试",
            )

    # 捕获其他未知异常
    except Exception as e:
        logger.error(f"用户 {current_user.id} 查询订单时发生未知错误: {type(e).__name__}: {str(e)}",
                     exc_info=True)  # 记录完整堆栈
        raise HTTPException(
            status_code=500,
            detail="服务器内部错误",
            headers={"X-Error": "InternalServerError"}
        )


# 订单后端代码中 order_api 路由组内
@order_api.get("/total", summary="订单总数统计", dependencies=[Depends(require_admin)])
async def order_total():
    """获取所有订单的总数量"""
    try:
        # 统计所有订单（可根据需求添加状态过滤，如排除已取消订单）
        total = await Order.all().count()
        # 如需过滤：await Order.filter(status!="已取消").count()

        return {
            "code": 200,
            "message": "订单总数统计成功",
            "data": {
                "order_total": total
            }
        }
    except Exception as e:
        print(f"订单统计错误: {str(e)}")
        return {
            "code": 500,
            "message": f"订单统计失败: {str(e)}",
            "data": {}
        }

class OrderStatusUpdate(BaseModel):
    status: str

@order_api.put("/{id}/status")  # 正确的路径参数格式：{id}
async def update_order_status(id: int, update_data: OrderStatusUpdate):
    try:
        # 查询订单是否存在
        order = await Order.get_or_none(id=id)
        if not order:
            raise HTTPException(status_code=404, detail="订单不存在")

        # 仅更新状态字段
        order.status = update_data.status
        await order.save()

        # 返回响应
        return {
            "code": 200,
            "message": "订单状态更新成功",
            "data": {
                "order_id": id,
                "new_status": order.status,
                "update_time": order.updated_at
            }
        }
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"服务器错误：{str(e)}")




@order_api.get("/", summary="管理员查询所有订单")
async def get_all_orders(
        page: int = Query(1, ge=1, description="页码"),
        page_size: int = Query(10, ge=1, le=100, description="每页数量"),
        order_number: Optional[str] = Query(None, description="订单号筛选"),
        status: Optional[str] = Query(None, description="订单状态筛选"),
        payment_status: Optional[str] = Query(None, description="支付状态筛选"),
):
    """
    管理员查询所有订单（支持分页和筛选）
    - 需要管理员权限
    - 支持按订单号、状态、支付状态筛选
    - 支持按日期范围筛选
    - 返回完整订单信息包括用户信息和订单项
    """
    try:
        logger.info(f"管理员开始查询所有订单 page={page}, page_size={page_size}")

        # 构建基础查询
        query = Order.all()

        # 应用筛选条件
        if order_number:
            query = query.filter(order_number__icontains=order_number)
        if status:
            query = query.filter(status=status)
        if payment_status:
            query = query.filter(payment_status=payment_status)

        # 计算总数（用于分页）
        total_count = await query.count()

        # 应用分页并预加载关联数据
        orders = await query.offset((page - 1) * page_size).limit(page_size).prefetch_related(
            "user",  # 预加载用户信息
            "address",  # 预加载地址信息
            "items"  # 预加载订单项
        ).order_by("-created_at")  # 按创建时间降序

        # 构建响应数据
        order_list = []
        for order in orders:
            # 处理用户信息
            user_data = {
                "id": order.user.id,
                "username": order.user.username,
                "phone": order.user.phone,
                # 添加其他需要的用户字段
            } if order.user else None

            # 处理地址信息
            address_data = {
                "id": order.address.id,
                "name": order.address.recipient_name,
                "phone": order.address.phone,
                "full_address": f"{order.address.province}{order.address.city}{order.address.county}{order.address.detail_address}"
                # 根据实际UserAddress字段调整
            } if order.address else None

            # 处理订单项
            order_items = []
            for item in order.items:
                order_items.append({
                    "id": item.id,
                    "product_id": item.product_id,
                    "product_type": item.product_type,
                    "product_name": item.product_name,
                    "product_image": item.product_image,
                    "price": float(item.price),
                    "quantity": item.quantity,
                    "total_price": float(item.total_price)
                })

            # 构建订单数据
            order_data = {
                "id": order.id,
                "order_number": order.order_number,
                "user": user_data,
                "total_amount": float(order.total_amount),
                "status": order.status,
                "payment_method": order.payment_method,
                "payment_status": order.payment_status,
                "refund_status": order.refund_status,
                "payment_at": order.payment_at.isoformat() if order.payment_at else None,
                "remark": order.remark,
                "created_at": order.created_at.isoformat(),
                "updated_at": order.updated_at.isoformat(),
                "address": address_data,
                "items": order_items
            }
            order_list.append(order_data)

        return {
            "code": 200,
            "message": "查询成功",
            "data": {
                "items": order_list,
                "total": total_count,
                "page": page,
                "page_size": page_size,
                "total_pages": (total_count + page_size - 1) // page_size
            }
        }

    except OperationalError as db_err:
        logger.error(f"管理员查询订单时数据库异常: {str(db_err)}")
        raise HTTPException(
            status_code=503,
            detail="服务暂时不可用，请稍后重试",
            headers={"X-Error": "DatabaseError"}
        )
    except Exception as e:
        logger.error(f"管理员查询订单时发生未知错误: {type(e).__name__}: {str(e)}", exc_info=True)
        raise HTTPException(
            status_code=500,
            detail="服务器内部错误",
            headers={"X-Error": "InternalServerError"}
        )


@order_api.get("/my/orders", summary="用户查询自己的订单列表")
async def get_my_orders(
        page: int = Query(1, ge=1, description="页码"),
        page_size: int = Query(10, ge=1, le=100, description="每页数量"),
        order_number: Optional[str] = Query(None, description="订单号筛选"),
        status: Optional[str] = Query(None, description="订单状态筛选"),  # 发货状态
        payment_status: Optional[str] = Query(None, description="支付状态筛选"),
        current_user: User = Depends(get_current_active_user)  # 获取当前登录用户
):
    """
    用户查询自己的订单列表（支持分页和筛选）
    - 仅能查询当前登录用户的订单
    - 支持按订单号、发货状态、支付状态筛选
    - 支持分页
    """
    try:
        logger.info(
            f"用户 {current_user.id} 查询订单列表 "
            f"page={page}, page_size={page_size}, "
            f"order_number={order_number}, status={status}, payment_status={payment_status}"
        )

        # 基础查询：只查询当前用户的订单
        query = Order.filter(user_id=current_user.id)

        # 应用筛选条件
        if order_number:
            query = query.filter(order_number__icontains=order_number)
        if status:
            query = query.filter(status=status)
        if payment_status:
            query = query.filter(payment_status=payment_status)

        # 获取总数（用于分页）
        total = await query.count()

        # 执行查询（带分页和排序）
        orders = await query.order_by("-created_at").offset(
            (page - 1) * page_size
        ).limit(page_size).prefetch_related(
            "address",  # 预加载地址信息
            "items"  # 预加载订单项
        )

        # 构造响应数据
        return {
            "code": 200,
            "message": "查询成功",
            "data": {
                "total": total,
                "page": page,
                "page_size": page_size,
                "items": [
                    {
                        "id": order.id,
                        "order_number": order.order_number,
                        "total_amount": float(order.total_amount),
                        "status": order.status,  # 发货状态
                        "payment_method": order.payment_method,
                        "payment_status": order.payment_status,  # 支付状态
                        "refund_status": order.refund_status,
                        "created_at": order.created_at,
                    } for order in orders
                ]
            }
        }

    except Exception as e:
        logger.error(f"用户 {current_user.id} 查询订单列表失败: {str(e)}")
        raise HTTPException(status_code=500, detail="服务器内部错误")




class OrderItemIn(BaseModel):
    product_id: int
    product_name: str
    product_type: ProductTypeEnum
    product_image: str
    quantity: int
    price: float
    total_price: float


class OrderIn(BaseModel):
    user_id: int  # 用户ID
    address_id: int  # 地址ID
    order_number: Optional[str]  # 订单编号
    total_amount: float  # 订单总金额
    status: str  # 订单状态: 待发货, 待收货, 待评价, 已完成, 已取消
    payment_method: str  # 支付方式
    payment_status: str  # 支付状态: 待支付, 支付成功, 支付失败
    remark: str  # 订单备注
    refund_status: str  # 退款状态
    items: List[OrderItemIn]


def generate_order_number():
    """生成唯一的订单号"""
    timestamp = int(time.time())
    random_num = random.randint(1000, 9999)
    return f"{timestamp}{random_num}"
@order_api.post("/")
async def addOrder(order: OrderIn):
    try:
        # 验证用户是否存在
        user = await User.get_or_none(id=order.user_id)
        if not user:
            raise HTTPException(status_code=400, detail="用户不存在")

        # 验证地址是否存在并且属于该用户
        address = await UserAddress.get_or_none(
            id=order.address_id,
            user_id=order.user_id
        )
        if not address:
            raise HTTPException(status_code=400, detail="地址不存在或不属于该用户")

        # 验证支付方式
        valid_payment_methods = ["微信支付", "支付宝支付", "货到付款"]
        if order.payment_method not in valid_payment_methods:
            raise HTTPException(status_code=400, detail="支付方式不支持")

        # 验证商品库存并计算总金额
        total_amount = Decimal(0)
        validated_items = []

        for item in order.items:
            # 根据商品类型查询不同的表
            if item.product_type == "coffee":
                product = await CoffeeProduct.get_or_none(id=item.product_id)
            elif item.product_type == "merchandise":
                product = await MerchandiseProduct.get_or_none(id=item.product_id)
            else:
                raise HTTPException(status_code=400, detail="无效的商品类型")

            if not product:
                raise HTTPException(status_code=400, detail=f"商品ID {item.product_id} 不存在")

            if product.stock < item.quantity:
                raise HTTPException(status_code=400, detail=f"商品 {product.name} 库存不足")

            # # 验证单价是否一致（防止前端篡改价格）
            # if abs(Decimal(str(item.price)) - product.price) > Decimal('0.01'):
            #     raise HTTPException(status_code=400, detail="商品价格不匹配")
            #
            item_total = Decimal(str(item.price)) * item.quantity
            if abs(item_total - Decimal(str(item.total_price))) > Decimal('0.01'):
                raise HTTPException(status_code=400, detail="商品总价计算错误")

            total_amount += item_total
            validated_items.append((product, item))

        # 验证订单总金额是否匹配
        if abs(total_amount - Decimal(str(order.total_amount))) > Decimal('0.01'):
            raise HTTPException(status_code=400, detail="订单总金额计算错误")

        # 生成订单号
        order_number = generate_order_number()

        # 创建订单
        new_order = await Order.create(
            user_id=order.user_id,
            address_id=order.address_id,
            order_number=order_number,
            total_amount=float(total_amount),
            status=order.status,
            payment_method=order.payment_method,
            payment_status=order.payment_status,
            remark=order.remark,
            refund_status=order.refund_status
        )

        # 创建订单项并更新库存
        for product, item in validated_items:
            await OrderItem.create(
                order_id=new_order.id,
                product_id=item.product_id,
                product_name=item.product_name,
                product_type=item.product_type,
                product_image=item.product_image,
                quantity=item.quantity,
                price=float(Decimal(str(item.price))),
                total_price=float(Decimal(str(item.price)) * item.quantity)
            )

            # 更新库存
            if item.product_type == "coffee":
                await CoffeeProduct.filter(id=item.product_id).update(
                    stock=product.stock - item.quantity
                )
            elif item.product_type == "merchandise":
                await MerchandiseProduct.filter(id=item.product_id).update(
                    stock=product.stock - item.quantity
                )

        return {
            "code": 200,
            "message": "添加成功",
            "data": {"order_number": order_number}
        }

    except HTTPException:
        raise  # 重新抛出HTTPException以便FastAPI处理

    except Exception as e:
        return {
            "code": 500,
            "message": f"服务器错误: {str(e)}"
        }

@order_api.delete("/{id}")
async def deleteOrder(id:int):
    await Order.filter(id=id).delete()

    return {
        "code":200,
        "message":"删除成功"
    }


class OrderItemUpdate(BaseModel):
    product_id:int
    quantity: int
class OrderUpdate(BaseModel):
    user_id: int
    address_id: int  # 允许修改收货地址
    status: str  # 允许修改订单状态（如发货、取消等）
    payment_status: str  # 允许修改支付状态
    remark: str  # 允许修改备注
    refund_status: str  # 允许修改退款状态
@order_api.put("/{id}")
async def updateOrder(id:int,update_data: OrderUpdate):
    try:
        # 1. 查询订单是否存在
        order = await Order.get_or_none(id=id)
        if not order:
            raise HTTPException(status_code=404, detail="订单不存在")

        # 3. 处理可修改的字段
        if update_data.address_id is not None:
            # 验证新地址是否属于该用户
            address = await UserAddress.get_or_none(
                id=update_data.address_id,
                user_id=update_data.user_id
            )
            if not address:
                raise HTTPException(status_code=400, detail="地址不存在或不属于该用户")
            order.address_id = update_data.address_id

            order.status = update_data.status

        if update_data.payment_status is not None:
            # 验证支付状态变更（例如：只能从"待支付"变为"支付成功"）
            if order.payment_status == "支付成功" and update_data.payment_status == "支付失败":
                raise HTTPException(status_code=400, detail="支付状态已确认，无法修改")
            order.payment_status = update_data.payment_status

        if update_data.remark is not None:
            order.remark = update_data.remark

        if update_data.refund_status is not None:
            order.refund_status = update_data.refund_status

        # # 4. 处理订单项修改（谨慎！可能涉及库存和金额重新计算）
        # if update_data.items is not None:
        #     # 警告：实际业务中通常不允许直接修改订单项，而是建议取消订单后重新下单
        #     raise HTTPException(status_code=400, detail="订单项不可直接修改，请取消后重新下单")

        # 5. 保存订单更新
        await order.save()

        return {
            "code": 200,
            "message": "订单更新成功"
        }

    except HTTPException:
        raise


# @order_api.get("/get_order/{id}")
# async def get_order(id:int):
#     user = await User.get(id=id)
#     order = await user.orders.all()
#     print()

@order_api.get("/user/{user_id}")
async def get_orders_by_user(user_id: int):
    """根据用户ID查询该用户的所有订单及订单项"""
    try:
        # 验证用户是否存在
        user = await User.get_or_none(id=user_id)
        if not user:
            raise HTTPException(status_code=404, detail="用户不存在")

        # 查询该用户的所有订单，按创建时间倒序排列
        orders = await Order.filter(user_id=user_id).order_by("-created_at").all()

        if not orders:
            return {
                "code": 200,
                "message": "该用户暂无订单",
                "data": []
            }

        # 构建包含订单项的完整订单数据
        result = []
        for order in orders:
            # 查询当前订单的所有订单项
            order_items = await OrderItem.filter(order_id=order.id).all()

            result.append({
                "order_id": order.id,
                "order_number": order.order_number,
                "total_amount": order.total_amount,
                "status": order.status,
                "payment_method": order.payment_method,
                "payment_status": order.payment_status,
                "remark": order.remark,
                "refund_status": order.refund_status,
                "created_at": order.created_at,  # 假设Order模型有创建时间字段
                "address_id": order.address_id,
                "items": [
                    {
                        "product_id": item.product_id,
                        "product_name": item.product_name,
                        "product_type": item.product_type,
                        "product_image": item.product_image,
                        "quantity": item.quantity,
                        "price": item.price,
                        "total_price": item.total_price
                    }
                    for item in order_items
                ]
            })

        return {
            "code": 200,
            "message": "查询成功",
            "data": result
        }

    except HTTPException:
        raise  # 重新抛出HTTP异常
    except Exception as e:
        return {
            "code": 500,
            "message": f"查询失败: {str(e)}"
        }

@order_api.get("/{order_num}")
async def get_order_by_order_num(order_num: int):
    order = await Order.get(order_number=order_num)
    return {
                "code": 200,
                "message": "查询成功",
                "data": order
            }


@order_api.put("/{order_id}/pay", summary="确认订单支付")
async def confirm_payment(
        order_id: int,
        current_user: User = Depends(get_current_active_user)
):
    try:
        # 1. 查询订单（确保订单存在且属于当前用户）
        order = await Order.get_or_none(id=order_id, user_id=current_user.id)
        if not order:
            raise HTTPException(
                status_code=404,
                detail="订单不存在或不属于当前用户"
            )

        # 2. 验证订单状态（核心修正）
        # 只有当支付状态不是"pending"（待支付）时，才拒绝支付
        if order.payment_status != "待支付":
            # 错误信息修正：明确当前状态
            raise HTTPException(
                status_code=400,
                detail=f"当前订单状态为{order.payment_status}（非待支付），无法执行支付操作"
            )

        # 3. 更新订单状态（待支付 → 已支付）
        order.payment_status = "已支付"  # 支付状态改为“已支付”
        order.status = ("待发货")  # 订单状态改为“处理中”（根据业务调整）
        order.payment_at = datetime.datetime.now()  # 记录支付时间
        await order.save()  # 保存到数据库

        # 4. 返回成功响应
        return {
            "code": 200,
            "message": "支付成功",
            "data": {
                "order_number": order.order_number,
                "payment_status": order.payment_status
            }
        }

    # 捕获已知异常（返回对应状态码）
    except HTTPException as e:
        raise e  # 直接抛出FastAPI定义的异常（会返回对应的400/404状态码）

    # 捕获其他未知异常（避免500错误，返回明确信息）
    except Exception as e:
        # 打印错误详情（方便调试）
        print(f"支付处理异常: {str(e)}")
        # 返回友好的错误提示
        raise HTTPException(
            status_code=500,
            detail=f"支付失败：服务器处理错误（{str(e)}）"
        )